package com.futao.niudong.controller;

import com.alibaba.fastjson.JSON;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;

/**
 * @author futao@gmail.com
 * @date 2022/3/14
 */
@Slf4j
@RestController
@RequestMapping("/es/index")
public class AnalyzeController {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @GetMapping("/analyze")
    public void analyze() throws IOException {
        AnalyzeRequest analyzeRequest = AnalyzeRequest.withGlobalAnalyzer("ik_max_word", "我是全中国最帅的男人");
        AnalyzeResponse analyzeResponse = restHighLevelClient.indices().analyze(analyzeRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(analyzeResponse, true));
    }

    /**
     * 索引不可重复创建
     *
     * @throws IOException
     */
    @PostMapping("/index")
    public void createIndex() throws IOException {
        // 索引名
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("ldk_api_index");
        Settings settings = Settings.builder()
                // 分片数量
                .put("index.number_of_shards", 5)
                // 副本数量
                .put("index.number_of_replicas", 3)
                .build();
        // 分片和副本设置
        createIndexRequest.settings(settings);
        // 字段映射
        // HashMap<String, Object> source = new HashMap<>();
        // HashMap<Object, Object> properties = new HashMap<>();
        // HashMap<Object, Object> messageField = new HashMap<>();
        // messageField.put("type", "text");
        // properties.put("properties", messageField);
        // source.put("message", properties);
        // createIndexRequest.mapping(source);
        createIndexRequest.mapping(" {\n" +
                "    \"book\":{  \n" +
                "      \"properties\": {\n" +
                "        \"id\": {\n" +
                "          \"type\": \"integer\"\n" +
                "        },\n" +
                "        \"name\": {\n" +
                "          \"type\": \"keyword\"\n" +
                "        },\n" +
                "        \"price\": {\n" +
                "          \"type\": \"double\"\n" +
                "        },\n" +
                "        \"detail\": {\n" +
                "          \"type\": \"text\"\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  }", XContentType.JSON);

        // 设置别名
        createIndexRequest.alias(new Alias("ldk_api_index_alias"));
        // 等待所有节点确认创建索引的超时时间
        createIndexRequest.setTimeout(TimeValue.timeValueMinutes(2L));
        // 等待连接到主节点的超时时间
        createIndexRequest.setMasterTimeout(TimeValue.timeValueMinutes(1));
        // 在请求返回前活动状态的分片数量
        createIndexRequest.waitForActiveShards(ActiveShardCount.from(2));
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(createIndexResponse, true));
    }

    @GetMapping("/index")
    public void index(@RequestParam("indexName") String indexName) throws IOException {
        org.elasticsearch.action.admin.indices.get.GetIndexRequest getIndexRequest = new org.elasticsearch.action.admin.indices.get.GetIndexRequest();
        getIndexRequest.indices(indexName);
        // 是否包含未设置的默认值
        getIndexRequest.includeDefaults(true);
        // 控制解析不可用索引及展开通配符表达式
        getIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
        GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        ImmutableOpenMap<String, MappingMetadata> objectObjectCursors = getIndexResponse.getMappings().get(indexName);
        for (ObjectObjectCursor<String, MappingMetadata> objectObjectCursor : objectObjectCursors) {
            System.out.println(JSON.toJSONString(objectObjectCursor, true));
        }
        System.out.println(JSON.toJSONString(getIndexResponse, true));
    }

    @DeleteMapping("/index")
    public void deleteIndex() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest();
        deleteIndexRequest.indices("ldk_api_index");
        // 等待所有节点删除索引的确认超时时间
        deleteIndexRequest.timeout(TimeValue.timeValueMinutes(2));
        deleteIndexRequest.masterNodeTimeout("1m");
        deleteIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
        // 同步删除
        // DeleteIndexResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        // System.out.println(JSON.toJSONString(delete, true));
        // 异步删除
        restHighLevelClient.indices().deleteAsync(deleteIndexRequest, RequestOptions.DEFAULT, new ActionListener<AcknowledgedResponse>() {
            @Override
            public void onResponse(AcknowledgedResponse acknowledgedResponse) {
                log.info("delete response:{}", JSON.toJSONString(acknowledgedResponse, true));
            }

            @Override
            public void onFailure(Exception e) {
                log.error("失败", e);

            }
        });
    }

    @GetMapping("/index-exist")
    public void indexExist(@RequestParam("indexName") String indexName) throws IOException {
        org.elasticsearch.action.admin.indices.get.GetIndexRequest request = new GetIndexRequest();
        request.indices(indexName);
        request.local(false);
        request.humanReadable(false);
        request.includeDefaults(false);
        request.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
}
